package lumis.content.lock;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;

import lumis.content.ContentManagerFactory;
import lumis.content.core.ContentLocale;
import lumis.content.core.ContentVersion;
import lumis.content.core.LockType;
import lumis.portal.AccessDeniedException;
import lumis.portal.PortalException;
import lumis.portal.controller.ControllerException;
import lumis.portal.controller.ControllerXml;
import lumis.portal.dao.DaoException;
import lumis.portal.group.GroupConfig;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.transaction.ITransaction;
import lumis.portal.transaction.PortalTransactionFactory;
import lumis.util.log.ILogger;
import lumis.util.log.LoggerFactory;


/**
 * Controller responsible for receiving ajax calls to change the current lock state.
 * @version $Revision: 13092 $ $Date: 2011-05-28 18:19:06 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
public class LockController extends ControllerXml
{
	private static ILogger logger = LoggerFactory.getLogger(LockController.class);
	private static final int OP_LOCK = 1;
	private static final int OP_UNLOCK = 2;
	private static final int OP_STEAL = 3;
	private static final int OP_AUTOUNLOCK = 4;
	
	public LockController(HttpServletRequest request, HttpServletResponse response, PageContext pageContext) throws ControllerException, PortalException
	{
		super(request, response);
	}

	/**
	 * Changes the lock value and outputs if it has succeeded.
	 * @since 6.0.0
	 */
	public void changeLock()
	{
		ITransaction transaction = null;
		PrintWriter writer = null;
		try
		{
			int operation =  Integer.valueOf(request.getParameter("lumLockOperation")).intValue();
			
			//indicates that it is a call that came from the edit interface
			String contentLocaleId = request.getParameter("contentLocaleId");
			
			//indicates that it is a call that came from the administration list:
			String itemId = request.getParameter("itemId");
			
			String currentUser = sessionConfig.getUserId();
			//if came from either edit interface or admin list
			if((contentLocaleId != null && !"".equals(contentLocaleId)) || itemId != null)
			{
				transaction = PortalTransactionFactory.createTransaction();
				transaction.begin();
				ContentLocale contentLocale = null;
				
				//if it's from edit interface
				if(contentLocaleId != null)
				{
					//get content locale using the getContentLocale method from the ContentManager
					contentLocale = ContentManagerFactory.getContentManager().getContentLocale(contentLocaleId);
				}
				else
				{
					//if its from the admin list
					//gets the content locale by first retrieving the version using the itemId
					ContentVersion contentVersion = ContentManagerFactory.getContentManager().getContentVersionByItemId(itemId);
					contentLocale =  contentVersion.getContentLocale();
				}
				
				//see if the user has access to edit in the current state of the workflow
				writer = response.getWriter();
				if(!(ContentManagerFactory.getWorkflowManager().hasEditPermission(sessionConfig, contentLocale, transaction) || 
					ManagerFactory.getGroupManager().isMember(sessionConfig, GroupConfig.GROUP_PUBLISHERS_ID, sessionConfig.getUserId(), transaction)))
				{
					throw new AccessDeniedException();
				}
				
				//Should only unlock if the operations are: STEAL, UNLOCK or AUTOUNLOCK (unlock due to an automatic lock)
				if(operation == OP_STEAL || operation == OP_UNLOCK || operation == OP_AUTOUNLOCK)
				{
					//will only release the current lock if:
					//the operation is to steal
					//the operation is to unlock
					//the operation is an unlock due to a LockType.AUTOMATIC and the publisher trying to unlock it is the same publisher that locked it 
					if( operation == OP_STEAL || 
						operation == OP_UNLOCK ||
							(operation == OP_AUTOUNLOCK && (LockType.AUTOMATIC.equals(contentLocale.getLockType()) 
															&& currentUser.equals(contentLocale.getLockedBy())
															)))
					{
						ContentManagerFactory.getContentManager().releaseLock(contentLocale.getId());
					}
				}

				//lock content to current user
				if(operation == OP_STEAL || operation == OP_LOCK)
				{
					ContentManagerFactory.getContentManager().lock(contentLocale.getId(), LockType.EXPLICIT);
				}
					
				transaction.commit();
				writer.write(getResponseXml("<success />"));
			}
		}
		catch (Exception e)
		{
			if(writer != null)
			{
				writer.write(getResponseXml("<failure>"+ e.getLocalizedMessage() +"</failure>"));
			}
			logger.error("Error in LockController.", e);
		}
		finally
		{
			if(transaction != null)
			{
				try
				{
					transaction.dispose();
				}
				catch (DaoException e){ logger.error("Error in LockController.", e); }
			}
		}
	}
}
